﻿oneAPI_PATH = D:/Intel/oneAPI/compiler/2023.1.0/windows
oneMKL_HOME = D:/Intel/oneAPI/mkl/2023.1.0
CUDA_HOME = D:/CUDA/v12.0
VS_LIBS_HOME = $(VS2019INSTALLDIR)/VC/Tools/MSVC/14.29.30133/lib/x64

SOLVER_DLL_LIBS= $(oneAPI_LIBS)\
				"$(VS_LIBS_HOME)/libcpmt.lib" "$(VS_LIBS_HOME)/libcmt.lib" "$(VS_LIBS_HOME)/oldnames.lib" "$(VS_LIBS_HOME)/vcomp.lib"\
				"$(VS_LIBS_HOME)/libvcruntime.lib" \
				"D:\Windows Kits\10\Lib\10.0.19041.0\um\x64\Uuid.lib" \
				"D:\Windows Kits\10\Lib\10.0.19041.0\um\x64\shell32.lib" \
				"D:\Windows Kits\10\Lib\10.0.19041.0\um\x64\Advapi32.lib" \
				"D:\Windows Kits\10\Lib\10.0.19041.0\um\x64\kernel32.lib" \
				"D:\Windows Kits\10\Lib\10.0.19041.0\ucrt\x64\libucrt.lib" \
				"D:\Windows Kits\10\Lib\10.0.19041.0\um\x64\ImageHlp.lib" \

# oneAPI_PATH = C:/zongyi/Intel/oneAPI/compiler/2023.2.0/windows
# oneMKL_HOME = C:/zongyi/Intel/oneAPI/mkl/2023.2.0
# CUDA_HOME = C:/zongyi/CUDA/v12.3
# VS_LIBS_HOME = $(VS2019INSTALLDIR)/VC/Tools/MSVC/14.29.30133/lib/x64

# SOLVER_DLL_LIBS= $(oneAPI_LIBS)\
# 				"$(VS_LIBS_HOME)/libcpmt.lib" "$(VS_LIBS_HOME)/libcmt.lib" "$(VS_LIBS_HOME)/oldnames.lib" "$(VS_LIBS_HOME)/vcomp.lib"\
# 				"$(VS_LIBS_HOME)/libvcruntime.lib" \
# 				"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x64\Uuid.lib" \
# 				"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x64\shell32.lib" \
# 				"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x64\Advapi32.lib" \
# 				"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x64\kernel32.lib" \
# 				"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\ucrt\x64\libucrt.lib" \
# 				"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x64\ImageHlp.lib" \

oneAPI_LIBS_HOME = $(oneAPI_PATH)/compiler/lib/intel64_win
oneAPI_LIBS = $(oneAPI_LIBS_HOME)/libircmt.lib $(oneAPI_LIBS_HOME)/svml_dispmt.lib $(oneAPI_LIBS_HOME)/libdecimal.lib \
			$(oneAPI_LIBS_HOME)/libmmt.lib $(oneAPI_LIBS_HOME)/libiomp5md.lib $(oneAPI_LIBS_HOME)/libirc.lib

oneMKL_INC = $(oneMKL_HOME)/include
oneMKL_LIB = $(oneMKL_HOME)/lib/intel64
LAPACK = $(oneMKL_LIB)/mkl_lapack95_lp64.lib $(oneMKL_LIB)/mkl_blas95_lp64.lib $(oneMKL_LIB)/mkl_intel_lp64.lib $(oneMKL_LIB)/mkl_intel_thread.lib $(oneMKL_LIB)/mkl_core.lib 

CUDA_INC = $(CUDA_HOME)/include
CUDA_LIBS_HOME = $(CUDA_HOME)/lib/x64
CUDA_LIBS = $(CUDA_LIBS_HOME)/cudart_static.lib $(CUDA_LIBS_HOME)/cublas.lib $(CUDA_LIBS_HOME)/cusolver.lib


GLUE_DLL_LIBS = $(SOLVER_DLL_LIBS) \
				$(oneAPI_LIBS_HOME)/ifmodintr.lib $(oneAPI_LIBS_HOME)/ifconsol.lib $(oneAPI_LIBS_HOME)/libifcoremt.lib \
				$(oneAPI_LIBS_HOME)/libifport.lib

CXX = $(oneAPI_PATH)/bin/icpx.exe
IFORT = $(oneAPI_PATH)/bin/ifx.exe
NVCC = $(CUDA_HOME)/bin/nvcc.exe
CFLAGS = -O3 -openmp -std=c++17 -march=native -ffast-math $(OPT)
NV_ARCH= -gencode arch=compute_75,code=sm_75 # 注意如果这里与机器型号不匹配的话，可能会出现异常结果
NVFLAGS= -O3 -std=c++17 -use_fast_math $(NV_ARCH) -Xcompiler -openmp $(OPT) # --default-stream per-thread

all: solDensMatrixFinalRound.dll test.exe

# 胶水部分
solDensMatrixFinalRound.dll: glue.o shared.o FracSolver.o  utils.o iterat_solver.o direct_solver.o gpu_direct_solver.o gpu_iterat_solver.o gpu_helper.o
	$(IFORT) /dll $^ $(CUDA_LIBS) $(LAPACK) $(GLUE_DLL_LIBS) -o $@

glue.o: solDensMatrixFinalRound.f90
	$(IFORT) -c $^ -O3 -openmp /fp:fast -I$(oneMKL_INC)/intel64/lp64 -I$(oneMKL_INC)  -o $@

# 核心部分
test.exe: main.o FracSolver.o utils.o iterat_solver.o direct_solver.o gpu_direct_solver.o gpu_iterat_solver.o gpu_helper.o
	$(CXX) $^ $(LAPACK) $(oneAPI_LIBS) $(CUDA_LIBS) -o $@ 
benchmark.exe: benchmark.cu
	$(NVCC) $^ $(NVFLAGS) -I$(CUDA_INC) -o $@ $(CUDA_LIBS) 

main.o: main.cpp
	$(CXX) -c $^ $(CFLAGS) -I$(oneMKL_INC) -I$(CUDA_INC) -o $@
shared.o: sharedlib.cpp
	$(CXX) -c $^ $(CFLAGS) -I$(oneMKL_INC) -I$(CUDA_INC) -o $@
FracSolver.o: FracSolver.cpp
	$(CXX) -c $^ $(CFLAGS) -I$(oneMKL_INC) -I$(CUDA_INC) -o $@

utils.o: utils.cpp
	$(CXX) -c $^ $(CFLAGS) -I$(oneMKL_INC) -o $@
iterat_solver.o: iterat_solver.cpp
	$(CXX) -c $^ $(CFLAGS) -I$(oneMKL_INC) -o $@
direct_solver.o: direct_solver.cpp
	$(CXX) -c $^ $(CFLAGS) -I$(oneMKL_INC) -o $@

gpu_direct_solver.o: gpu_direct_solver.cu
	$(NVCC) -c $^ $(NVFLAGS) -I$(CUDA_INC) -o $@
gpu_iterat_solver.o: gpu_iterat_solver.cu
	$(NVCC) -c $^ $(NVFLAGS) -I$(CUDA_INC) -o $@
gpu_helper.o: gpu_helper.cu
	$(NVCC) -c $^ $(NVFLAGS) -I$(CUDA_INC) -o $@


clean:
	del *.o *.mod *.exe *.dll *.lib *.exp *.obj
